using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using Yoozoo.Gameplay.Liberty;
using Yoozoo.Modules.Update;
using Yoozoo.UI.YGUI;

namespace Yoozoo.Core.Timeline
{
    public class PlayerCharacterController : MonoBehaviour
    {
        [Serializable]
        public struct trackBindingItem
        {
            public string Name;
            public bool isAnimator;
            public GameObject[] objs;
        }

        [SerializeField] public trackBindingItem[] items;
        [SerializeField] public YText[] names;

        int index = 0;
        PlayableDirector director;

        void Start()
        {
            director = this.gameObject.GetComponent<PlayableDirector>();
            RefreshCharacter();
        }

        private Dictionary<string, UnityEngine.Object> Name_BindObj = new Dictionary<string, UnityEngine.Object>();
        private Dictionary<string, GameObject> Target_BindObj = new Dictionary<string, GameObject>();
        private Dictionary<string, Animator> Target_BindAni = new Dictionary<string, Animator>();

        public void RefreshCharacter()
        {
            var idx = TimelineConstructorMgr.GetInstance("TimelineConstructorMgr")?.GetTimelineCharacterId();
            if (idx != null)
            {
                index = (int)idx;
                CreateTrackDir();
                GetAllOuts();
                RefreshNames();
            }
        }

        private void RefreshNames()
        {
            string nickname = GetPlayerName();
            foreach (YText textObj in names)
            {
                textObj.text = nickname;
            }
        }

        private void CreateTrackDir()
        {
            Target_BindObj.Clear();
            Target_BindAni.Clear();
            
            foreach (trackBindingItem item in items)
            {
                GameObject obj;
                Animator ani;
                for (int idx = 0; idx < item.objs.Length; idx++)
                {
                    obj = item.objs[idx];
                    
                    if (idx == index)
                    {
                        if (item.isAnimator)
                        {
                            ani = obj.GetComponent<Animator>();
                            Target_BindAni.Add(item.Name, ani);
                        }
                        else
                        {
                            Target_BindObj.Add(item.Name, obj);
                        }
                        obj.SetActive(true);
                    }
                    else
                    {
                        obj.SetActive(false);
                    }
                }
            }
        }
        
        private void GetAllOuts()
        {
            Name_BindObj.Clear();
            
            foreach (PlayableBinding item in director.playableAsset.outputs)
            {
                //Debug.LogError("item.streamName = " + item.streamName);
                if (!Name_BindObj.TryGetValue(item.streamName, out var obj))
                {
                    var gameObj = GameObject.Find(item.streamName);
                    Name_BindObj.Add(item.streamName, item.sourceObject);
                    CheckTrack(item.streamName);
                }
            }
        }

        private void CheckTrack(string trackName)
        {
            if (Target_BindObj.ContainsKey(trackName))
            {
                SetGenericBindObj(trackName, Target_BindObj[trackName]);
            }
            if (Target_BindAni.ContainsKey(trackName))
            {
                SetGenericBindAni(trackName, Target_BindAni[trackName]);
            }
        }

        private void SetGenericBindObj(string trackName, GameObject obj)
        {
            director.SetGenericBinding(Name_BindObj[trackName], obj);
        }
        
        private void SetGenericBindAni(string trackName, Animator ani)
        {
            director.SetGenericBinding(Name_BindObj[trackName], ani);
        }

        private string GetPlayerName()
        {
            if(DependencyInjection.LuaFuncStr == null)
                return "";

            return DependencyInjection.LuaFuncStr("L_Store.loginData", "staticGetPlayerName");
        }
    }
}